package org.nanotek.tika.io;

import static java.nio.file.FileVisitResult.CONTINUE;

import java.io.FileInputStream;
import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.PathMatcher;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;

import org.apache.log4j.Logger;
import org.apache.tika.io.TemporaryResources;
import org.apache.tika.io.TikaInputStream;
import org.nanotek.tika.MediaDetail;

public class TikaFileVisitor extends SimpleFileVisitor<Path> {

	protected PathMatcher matcher;
	private int numMatches = 0;
	private TikaMediaDetector  tikaMediaDetector;
	private static final Logger log = Logger.getLogger(TikaFileVisitor.class);
	
	public TikaFileVisitor() {
	}

	
	public TikaFileVisitor(String pattern) {
		matcher = FileSystems.getDefault().getPathMatcher("glob:" + pattern);
	}

	// Compares the glob pattern against
	// the file or directory name.
	void find(Path file) {
		Path name = file.getFileName();
		if (name != null && matcher.matches(name)) {
			numMatches++;
			String type;
			try {
				type = Files.probeContentType(file);
//				System.out.format("%s\t%s%n", file, type);
				visitFile(file);
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	// Prints the total number of
	// matches to standard out.
	public void done() {
		System.out.println("Matched: " + numMatches);
	}

	void visitFile(Path file) {
		Path name = file.getFileName();
		TikaInputStream input = null;
		if (name != null && matcher.matches(name)) {
			TemporaryResources tmp = null;
			numMatches++;
//			String type;
			try {
//				File targetFile = name.toFile();
//				System.out.format("%s\t", file.toString());
//				System.out.println();
				tmp = new TemporaryResources();
				input = TikaInputStream.get(new FileInputStream(file.toString()), tmp);
				MediaDetail mediaDetails = tikaMediaDetector.detectMediaType(input);
				mediaDetails.setLocation(file.toFile().getAbsolutePath());
//				type = Files.probeContentType(file);
//				System.out.format("%s\t", mediaDetails.toString());
//				System.out.println();
				log.debug(mediaDetails.toString());
			} catch (Exception e) {
				e.printStackTrace();
//				throw new RuntimeException(e);
			}finally {
				if (input !=null) {
					try {
						input.close();
						if (tmp !=null)
							tmp.dispose();
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
			}

		}
	}
	
	// Invoke the pattern matching
	// method on each file.
	@Override
	public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
		find(file);
		return CONTINUE;
	}

	// Invoke the pattern matching
	// method on each directory.
	@Override
	public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
		find(dir);
		return CONTINUE;
	}

	@Override
	public FileVisitResult visitFileFailed(Path file, IOException exc) {
		exc.printStackTrace();
		return CONTINUE;
	}

	public int getNumMatches() {
		return numMatches;
	}

	public void setNumMatches(int numMatches) {
		this.numMatches = numMatches;
	}

	public PathMatcher getMatcher() {
		return matcher;
	}

	public void setMatcher(PathMatcher matcher) {
		this.matcher = matcher;
	}


	public TikaMediaDetector getTikaMediaDetector() {
		return tikaMediaDetector;
	}


	public void setTikaMediaDetector(TikaMediaDetector tikaMediaDetector) {
		this.tikaMediaDetector = tikaMediaDetector;
	}
	
}
